package com.github.chirspan.xaas.api;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.github.chirspan.xaas.mybatis.annotation.EnableSelectOption;
import com.github.chirspan.xaas.mybatis.annotation.SelectOption;
import com.github.chirspan.xaas.mybatis.model.BaseModel;

import java.lang.reflect.Field;

/**
 * ************************
 * <p></p>
 * *************************
 *
 * @author chenpan
 * @date 2021/1/19 12:14
 */
public class BaseCRUDWrapper {

    public static final String ORDER_DESC_STR =" DESC";
    public static final String ORDER_ASC_STR = " ASC";

    public static <T extends BaseModel> QueryWrapper orderBy(QueryWrapper<T> queryWrapper, T m) {
        if (StrUtil.isBlank(m.getSortBy())) {
            queryWrapper.orderByDesc("create_time");
        } else {
            String[] orderByColumns = m.getSortBy().split(",");
            for (String column : orderByColumns) {
                String trimStr = StrUtil.trimEnd(column);
                if (StrUtil.endWithIgnoreCase(StrUtil.trimEnd(column), ORDER_DESC_STR)) {
                    queryWrapper.orderByDesc(StrUtil.replaceIgnoreCase(trimStr, ORDER_DESC_STR, ""));
                } else {
                    queryWrapper.orderByAsc(StrUtil.replaceIgnoreCase(trimStr, ORDER_ASC_STR, ""));
                }
            }
        }
        return queryWrapper;
    }

    public static <T extends BaseModel> QueryWrapper query(T m) {

        QueryWrapper<T> queryWrapper = new QueryWrapper(m);
        return orderBy(queryWrapper, m);
    }

    public static <T extends BaseModel> QueryWrapper baseQueryWrapper(T m) throws IllegalAccessException {

        QueryWrapper<T> queryWrapper = new QueryWrapper<>();
        //查询配置
        if (m.getClass().isAnnotationPresent(EnableSelectOption.class)) {
            Field[] fields = m.getClass().getDeclaredFields();
            for (Field field : fields) {
                SelectOption selectOption = field.getAnnotation(SelectOption.class);
                if (selectOption != null) {
                    //模糊查询
                    if (selectOption.likeColumn()) {
                        field.setAccessible(true);
                        Object fieldValue = field.get(m);
                        boolean notEmpty = fieldValue != null
                                && StrUtil.isNotEmpty((String) fieldValue);
                        if (notEmpty) {
                            switch (selectOption.wildcardPosition()) {
                                case BOTH:
                                    queryWrapper.like(field.getName(), fieldValue);
                                    BeanUtil.setFieldValue(m, field.getName(), null);
                                    break;
                                case AFTER:
                                    queryWrapper.likeRight(field.getName(), fieldValue);
                                    BeanUtil.setFieldValue(m, field.getName(), null);
                                    break;
                                case BEFORE:
                                    queryWrapper.likeLeft(field.getName(), fieldValue);
                                    BeanUtil.setFieldValue(m, field.getName(), null);
                                    break;
                                default:
                                    break;
                            }
                        }
                    }
                    //日期区间查询
                    if (selectOption.betweenDate()) {
                        field.setAccessible(true);
                        Object fieldValue = field.get(m);
                        Object startValue;
                        Object endValue;
                        switch (selectOption.datePosition()) {
                            case START:
                                startValue = fieldValue;
                                if (StrUtil.isNotEmpty(selectOption.startDateValueKey())) {
                                    startValue = BeanUtil.getFieldValue(m, selectOption.startDateValueKey());
                                }
                                if (startValue != null) {
                                    queryWrapper.ge(field.getName(), startValue);
                                }
                                break;
                            case END:
                                endValue = fieldValue;
                                if (StrUtil.isNotEmpty(selectOption.endDateValueKey())) {
                                    endValue = BeanUtil.getFieldValue(m, selectOption.endDateValueKey());
                                }
                                if (endValue != null) {
                                    queryWrapper.le(field.getName(), endValue);
                                }
                                break;
                            case START_AND_END:
                                if (StrUtil.isNotEmpty(selectOption.startDateValueKey())) {
                                    startValue = BeanUtil.getFieldValue(m, selectOption.startDateValueKey());
                                    if (startValue != null) {
                                        queryWrapper.ge(field.getName(), startValue);
                                    }
                                }
                                if (StrUtil.isNotEmpty(selectOption.endDateValueKey())) {
                                    endValue = BeanUtil.getFieldValue(m, selectOption.endDateValueKey());
                                    if (endValue != null) {
                                        queryWrapper.le(field.getName(), endValue);
                                    }
                                }

                                break;
                            default:
                                break;

                        }
                    }
                    BeanUtil.setFieldValue(m, field.getName(), null);
                }
            }
        }
        queryWrapper.setEntity(m);
        return orderBy(queryWrapper, m);
    }
}
